<!doctype html>
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>2.3.1 - FreeMarker 手册</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="FreeMarker 手册">
<meta property="og:title" content="2.3.1">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://freemarker.org/docs/versions_2_3_1.html">
<link rel="canoical" href="http://freemarker.org/docs/versions_2_3_1.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css">
</head>
<body itemscope itemtype="https://schema.org/Code">
    <meta itemprop="url" content="http://freemarker.org/docs/">
    <meta itemprop="name" content="FreeMarker 手册">

  <!--[if lte IE 9]>
  <div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
  <![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://freemarker.org" role="banner">            <img itemprop="image" src="logo.png" alt="FreeMarker">
</a><ul class="tabs"><li><a href="http://freemarker.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="http://freemarker.org/docs/api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="http://freemarker.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://sourceforge.net/p/freemarker/bugs/new/" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="http://freemarker.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="toc.html" class="navigation-header">Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="toc.html"><span itemprop="name">FreeMarker 手册</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app.html"><span itemprop="name">附录</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="app_versions.html"><span itemprop="name">版本历史</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="versions_2_3_1.html"><span itemprop="name">2.3.1</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div>    <div class="main-content site-width">
      <div class="content-wrapper">
  <div id="table-of-contents-wrapper" class="col-left">
      <script>var breadcrumb = ["FreeMarker 手册","附录","版本历史","2.3.1"];</script>
      <script src="toc.js"></script>
      <script src="docgen-resources/main.min.js"></script>
  </div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="versions_2_3_2.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="versions_2_3_1" itemprop="headline">2.3.1</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_194" data-menu-target="autoid_194">Possible backward compatibility issue</a></li><li><a class="page-menu-link" href="#autoid_195" data-menu-target="autoid_195">Changes on the FTL side</a></li><li><a class="page-menu-link" href="#autoid_196" data-menu-target="autoid_196">Changes on the Java side</a></li><li><a class="page-menu-link" href="#autoid_197" data-menu-target="autoid_197">Other changes</a></li><li><a class="page-menu-link" href="#autoid_198" data-menu-target="autoid_198">The history of the releases before the final version</a><ul><li><a class="page-menu-link" href="#autoid_199" data-menu-target="autoid_199">Differences between the preview release and final
release</a></li></ul></li></ul> </div><p>Date of release: 2005-01-04</p><p>Maintenance (with some important new features) and bugfix
        release.</p>
          



<h2 class="content-header header-section2" id="autoid_194">Possible backward compatibility issue</h2>


          <p>There is a bugfix that may affect the behavior of you Web
          application if you use JSP tags in FreeMarker templates:
          FreeMarker&#39;s implementation of
          <code class="inline-code">javax.servlet.jsp.PageContext.getSession()</code> was
          incorrect. The <code class="inline-code">getSession()</code> method is a
          convenience method by which the custom tag can get the current
          <code class="inline-code">HttpSession</code> object (possibly
          <code class="inline-code">null</code> if there is no session). Till now, if the
          session didn&#39;t existed then it has created it automatically, so it
          never returned <code class="inline-code">null</code>. This was a bug, so starting
          from 2.3.1 it never creates the session, just returns
          <code class="inline-code">null</code> if it doesn&#39;t exist. The old incorrect
          behavior could cause page rendering to fail if the method is called
          after the page is partially flushed. But beware, the old behavior
          has possibly hidden some bugs of the Web application, where it
          forgot to create the session, so with the new correct behavior you
          may face malfunction caused by previously cloaked bugs of the Web
          application. (It&#39;s the task of the MVC Controller to create the
          session, except if the JSP tag that needs a session is written so it
          creates it automatically, but then it doesn&#39;t expects that
          <code class="inline-code">getSession()</code> will do it.)</p>
        
          



<h2 class="content-header header-section2" id="autoid_195">Changes on the FTL side</h2>


          <ul>
            <li>
              <p>New built-in: <a href="ref_builtins_string.html#ref_builtin_url"><code>url</code></a>. This
              built-in can be used for URL escaping. Note, however, that to
              use this built-in conveniently, the software that encapsulates
              FreeMarker has to be 2.3.1 aware (programmers will find more
              info bellow...).</p>
            </li>

            <li>
              <p>New <a href="ref_specvar.html">special variables</a>:
              <code class="inline-code">output_encoding</code> and
              <code class="inline-code">url_escaping_charset</code>. Note, however, that to
              use these, the software that encapsulates FreeMarker has to be
              2.3.1 aware (programmers will find more info bellow...).</p>
            </li>

            <li>
              <p>New built-ins for sequences: <a href="ref_builtins_sequence.html#ref_builtin_seq_contains"><code>seq_contains</code></a>,
              <a href="ref_builtins_sequence.html#ref_builtin_seq_index_of"><code>seq_index_of</code></a>,
              <a href="ref_builtins_sequence.html#ref_builtin_seq_last_index_of"><code>seq_last_index_of</code></a>.</p>
            </li>

            <li>
              <p>New built-ins for strings: <a href="ref_builtins_string.html#ref_builtin_left_pad"><code>left_pad</code></a>,
              <a href="ref_builtins_string.html#ref_builtin_right_pad"><code>right_pad</code></a>
              and <a href="ref_builtins_string.html#ref_builtin_contains"><code>contains</code></a>.</p>
            </li>

            <li>
              <p>New directive: <a href="ref_directive_attempt.html#ref.directive.attempt"><code>attempt</code>/<code>recover</code></a></p>
            </li>

            <li>
              <p>The <a href="ref_builtins_string.html#ref_builtin_js_string"><code>js_string</code>
              built-in</a> now escapes <code class="inline-code">&gt;</code> as
              <code class="inline-code">\&gt;</code> (to avoid
              <code class="inline-code">&lt;/script&gt;</code>).</p>
            </li>

            <li>
              <p>The <code class="inline-code">sort</code> and <code class="inline-code">sort_by</code>
              built-ins now can sort by date values. Also,
              <code class="inline-code">sort_by</code> built-in now can sort by the
              subvarible of a subvariable of a subvariable... etc. for any
              level depth. (<a href="ref_builtins_sequence.html#ref_builtin_sort_by">Details...</a>)</p>
            </li>

            <li>
              <p><code class="inline-code">freemarker.template.TemplateExceptionHandler.HTML_DEBUG_HANDLER</code>
              now prints more HTML-context-proof messages.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_196">Changes on the Java side</h2>


          <ul>
            <li>
              <p>New setting: <code class="inline-code">output_encoding</code>. This
              setting is used for informing FreeMarker about the charset that
              the enclosing software (as a Web application framework) uses for
              the output of FreeMarker. It&#39;s undefined by default, and
              although it is not strictly required to set it, the enclosing
              software should do so. This setting must be set if templates
              want to use the new <code class="inline-code">output_encoding</code> special
              variable, and possibly if they want to use the new
              <code class="inline-code">url</code> built-in. Note that the FreeMarker API
              allows you to set settings for each template execution
              individually (look at
              <code class="inline-code">Template.createProcessingEnvironment(...)</code>).</p>
            </li>

            <li>
              <p>New setting: <code class="inline-code">url_escaping_charset</code>. This
              is the charset used for calculating the escaped parts
              (<code class="inline-code">%<em class="code-color">XX</em></code>) when you do
              URL escaping with the new <code class="inline-code">url</code> built-in. If it
              is not set, then the <code class="inline-code">url</code> built-in uses the
              value of the <code class="inline-code">output_encoding</code> setting, and if
              that&#39;s not set either, then the parameterless version of
              <code class="inline-code">url</code> built-in (<code class="inline-code">${foo?url}</code>)
              can&#39;t be used.</p>
            </li>

            <li>
              <p>Using the singleton (static)
              <code class="inline-code">Configuration</code> instance is clearly a bad
              practice, so related methods are now deprecated, and the Manual
              was adjusted, and the <code class="inline-code">FreemarkerXmlTask</code> was
              updated as well.</p>
            </li>

            <li>
              <p>The
              <code class="inline-code">freemarker.template.utility.Constants</code> class
              was added that contains various static final fields that store
              frequently used constant <code class="inline-code">TemplateModel</code>
              values, as <code class="inline-code">EMPTY_SEQUENCE</code>,
              <code class="inline-code">ZERO</code>, ...etc.</p>
            </li>

            <li>
              <p>When using <code class="inline-code">SecurityManager</code> with
              FreeMarker, accessing system properties may caused
              AccessControlException. Now such exceptions are catched and
              logged with warning level, and the default value of the property
              is returned.</p>
            </li>

            <li>
              <p>The needles <code class="inline-code">InvocationTargetException</code>
              is now removed from the exception cause trace in certain
              cases.</p>
            </li>

            <li>
              <p>Added a dirty hack that prints
              <code class="inline-code">ServletException</code> root cause in
              <code class="inline-code">TemplateException</code>&#39;s stack trace if that&#39;s the
              direct cause exception of the
              <code class="inline-code">TemplateException</code>, despite the poorly written
              <code class="inline-code">ServletException</code> class.</p>
            </li>

            <li>
              <p>Bugfix: FreeMarker&#39;s implementation of
              <code class="inline-code">javax.servlet.jsp.PageContext.getSession()</code>
              was incorrect. The <code class="inline-code">getSession()</code> method is a
              convenience method by which the custom tag can get the current
              <code class="inline-code">HttpSession</code> object (possibly
              <code class="inline-code">null</code> if there is no session). Till now, if
              the session didn&#39;t existed then it has created it automatically,
              so it never returned <code class="inline-code">null</code>. This was a bug, so
              starting from 2.3.1 it never creates the session, just returns
              <code class="inline-code">null</code> if it doesn&#39;t exist. The old incorrect
              behavior could cause page rendering to fail if the method is
              called after the page is partially flushed. But beware, the old
              behavior has possibly hidden some bugs of the Web application,
              where it forgot to create the session, so with the new correct
              behavior you may face malfunction caused by previously cloaked
              bugs of the Web application. (It&#39;s the task of the MVC
              Controller to create the session, except if the JSP tag that
              needs a session is written so it creates it automatically, but
              then it doesn&#39;t expects that <code class="inline-code">getSession()</code>
              will do it.)</p>
            </li>

            <li>
              <p>Bugfix: The <code class="inline-code">BeansWrapper</code> didn&#39;t always
              handled properly the case of a Java class having both a public
              static field and a public static method with the same
              name.</p>
            </li>

            <li>
              <p>Bugfix: <code class="inline-code">SimpleMethodModel</code> had
              incorrectly propagate exceptions sometimes, causing null pointer
              exception.</p>
            </li>

            <li>
              <p>Bugfix: The template execution may used outdated cached
              values when you have processed the same
              <code class="inline-code">Environment</code> for multiple times, and changed
              settings between the two processings. Note that this could
              happen only in single-thread environment, where such setting
              modifications are allowed.</p>
            </li>

            <li>
              <p>Bugfix: Some of the string built-ins has died with
              <code class="inline-code">IndexOutOfBounds</code> exception if the template
              author has forgotten to specify required parameters. Now they
              die with more helpful error messages.</p>
            </li>

            <li>
              <p>Bugfix:
              <code class="inline-code">freemarker.ext.dom.NodeModel.equals(...)</code> has
              died with null pointer exception if its argument was
              <code class="inline-code">null</code>.</p>
            </li>

            <li>
              <p>Bugfix: The cause exception of
              <code class="inline-code">TemplateException</code>-s was sometimes printed
              twice in stack traces with J2SE 1.4 or later.</p>
            </li>

            <li>
              <p>Bugfix: The
              <code class="inline-code">StringUtil.FTLStringLiteralEnc(String)</code> method
              was finished.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_197">Other changes</h2>


          <ul>
            <li>
              <p>Fixes and improvements in the Manual and in the API
              JavaDoc.</p>
            </li>
          </ul>
        
          



<h2 class="content-header header-section2" id="autoid_198">The history of the releases before the final version</h2>


          
            



<h3 class="content-header header-section3" id="autoid_199">Differences between the preview release and final
            release</h3>


            <ul>
              <li>
                <p>Added a dirty hack that prints
                <code class="inline-code">ServletException</code> root cause in
                <code class="inline-code">TemplateException</code>&#39;s stack trace if that&#39;s
                the direct cause exception of the
                <code class="inline-code">TemplateException</code>, despite the poorly
                written <code class="inline-code">ServletException</code> class.</p>
              </li>

              <li>
                <p>Bugfix:
                <code class="inline-code">freemarker.ext.dom.NodeModel.equals(...)</code>
                has died with null pointer exception if its argument was
                <code class="inline-code">null</code>.</p>
              </li>

              <li>
                <p>Bugfix: The cause exception of
                <code class="inline-code">TemplateException</code>-s was sometimes printed
                twice in stack traces with J2SE 1.4 or later.</p>
              </li>

              <li>
                <p>More minor improvements in the Manual.</p>
              </li>
            </ul>
          
        <div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="versions_2_3_2.html"><span>Previous</span></a><a class="paging-arrow next" href="versions_2_3.html"><span>Next</span></a></div></div></div></div>      </div>
    </div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="http://freemarker.org/index.html">What is FreeMarker?</a></li><li><a href="http://freemarker.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="http://freemarker.org/history.html">About us</a></li><li><a itemprop="license" href="app_license.html">License</a></li></ul></div><div class="column"><h3 class="column-header">Handy stuff</h3><ul><li><a href="http://freemarker-online.kenshoo.com/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/nanlei/freemarker/tree/manual-zh-2.3-gae/src/manual">Chinese Manual on Github</a></li><li><a href="https://github.com/freemarker/freemarker">FreeMarker on Github</a></li><li><a href="https://twitter.com/freemarker">Follow us on Twitter</a></li><li><a href="https://sourceforge.net/p/freemarker/bugs/new/">Report a bug</a></li><li><a href="http://stackoverflow.com/questions/ask?tags=freemarker">Ask a question</a></li><li><a href="http://freemarker.org/mailing-lists.html">Mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/freemarker/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="http://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"><p><span class="generated-for-product">Generated for: Freemarker 2.3.23</span><span class="last-updated"> Last generated:
<time itemprop="dateModified" datetime="2015-09-18T14:38:51Z" title="Friday, September 18, 2015 2:38:51 PM GMT">2015-09-18 14:38:51 GMT</time></span></p> <p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2015
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="http://freemarker.org">The FreeMarker Project</a>. All rights reserved. </p>
</div></div></div></body>
</html>
